#include <windows.h>
#include <sddl.h>
#include "uti_broadcast.h"
#include "uti_consolecolor.h"
using namespace std;

const unsigned int SEMRECORD_MAPSIZE = 50;
//
//Broadcast::Broadcast(BarInfo* pbar)
//{
//	memcpy(&m_barinfo, pbar, sizeof(BarInfo));
//
//	unsigned int size = sizeof(m_shmarr)/sizeof(SharedMemory);
//	for (unsigned int i = 0; i < size; i++)
//	{
//		unsigned sersize  = 0;
//		char* mqsuffix = NULL;
//		char* semrecsuffix = NULL;
//		BarInfo barinfo;
//		memcpy(&barinfo, &m_barinfo, sizeof(BarInfo));
//		if (0 == i)
//		{
//			sersize = DEFAULT_TICKSERSIZE_OFDAY;
//			mqsuffix = "tickmq";
//			semrecsuffix = "ticksem";
//			barinfo.type = Bartype::tick;
//		}		
//		else if (1 == i)
//		{
//			sersize = DEFAULT_SECSERSIZE_OFDAY;;
//			mqsuffix = "secmq";
//			semrecsuffix = "secsem";
//			barinfo.type = Bartype::sec;
//		}
//		else if (2 == i)
//		{
//			sersize = DEFAULT_MINSERSIZE_OFDAY;
//			mqsuffix = "minmq";
//			semrecsuffix = "minsem";
//			barinfo.type = Bartype::min;
//		}
//		else if (3 == i)
//		{
//			sersize = DEFAULT_DAYSERSIZE_OFDAY;
//			mqsuffix = "daymq";
//			semrecsuffix = "daysem";
//			barinfo.type = Bartype::day;
//		}
//
//		if (false == InitSharedMQ(i, sersize, mqsuffix))
//		{
//			printf("[Broadcast] InitSharedMQ:%s failed\n", mqsuffix);
//			return;
//		}
//
//		if (false == InitSharedSemRecord(i, semrecsuffix))
//		{
//			printf("[Broadcast] InitSharedSemRecord:%s failed\n", semrecsuffix);
//			return;
//		}
//
//		m_pbarserbroad[i] = new BarSeries_broad(&barinfo, sersize, NULL, m_shmarr[i].pmq_barser, m_shmarr[i].pindex_barser);
//		if (NULL == m_pbarserbroad[i])
//		{
//			printf("[Broadcast] m_pbarserbroad:%d init failed\n", i);
//			return;
//		}
//
//	}
//
//
//	if (false == InitMutex())
//	{
//		printf("[Broadcast] InitMutex failed\n");
//		return;
//	}
//
//}


Broadcast::Broadcast(string stringInst)
{
	//memcpy(&m_barinfo, pbar, sizeof(BarInfo));

	m_stringInst = stringInst;

	unsigned int size = sizeof(m_shmarr)/sizeof(SharedMemory);
	for (unsigned int i = 0; i < size; i++)
	{
		unsigned sersize  = 0;
		char* mqsuffix = NULL;
		char* semrecsuffix = NULL;
		BarInfo barinfo;
		//memcpy(&barinfo, &m_barinfo, sizeof(BarInfo));
		strcpy(barinfo.instru, m_stringInst.c_str());
		barinfo.cnt = 1;
		if (0 == i)
		{
			sersize = DEFAULT_TICKSERSIZE_OFDAY;
			mqsuffix = "tickmq";
			semrecsuffix = "ticksem";
			barinfo.type = Bartype::tick;
		}		
		else if (1 == i)
		{
			sersize = DEFAULT_SECSERSIZE_OFDAY;;
			mqsuffix = "secmq";
			semrecsuffix = "secsem";
			barinfo.type = Bartype::sec;
		}
		else if (2 == i)
		{
			sersize = DEFAULT_MINSERSIZE_OFDAY;
			mqsuffix = "minmq";
			semrecsuffix = "minsem";
			barinfo.type = Bartype::min;
		}
		else if (3 == i)
		{
			sersize = DEFAULT_DAYSERSIZE_OFDAY;
			mqsuffix = "daymq";
			semrecsuffix = "daysem";
			barinfo.type = Bartype::day;
		}

		if (false == InitSharedMQ(i, sersize, mqsuffix))
		{
			pantheios::log_ERROR("[Broadcast] InitSharedMQ", m_stringInst, ":", mqsuffix, " failed");
			return;
		}

		if (false == InitSharedSemRecord(i, semrecsuffix))
		{
			pantheios::log_ERROR("[Broadcast] InitSharedSemRecord", m_stringInst, ":", semrecsuffix, " failed");
			return;
		}

		m_pbarserbroad[i] = new BarSeries_broad(&barinfo, sersize, NULL, m_shmarr[i].pmq_barser, m_shmarr[i].pindex_barser);
		if (NULL == m_pbarserbroad[i])
		{
			pantheios::log_ERROR("[Broadcast] m_pbarserbroad:", panint(i), " init failed");
			return;
		}

	}


	if (false == InitMutex())
	{
		pantheios::log_ERROR("[Broadcast] InitMutex failed");
		return;
	}

}


Broadcast::~Broadcast()
{
	unsigned int size = sizeof(m_shmarr)/sizeof(SharedMemory);
	for (unsigned int i = 0; i < size; i++)
	{
		DestroySharedMQ(i);

		DestroySharedSemRecord(i);

		if (m_pbarserbroad[i])
			delete m_pbarserbroad[i];

	}

	DestroyMutex();
}


bool Broadcast::GetSecurityAttributes(SECURITY_ATTRIBUTES &securityAttributes)
{
	//SECURITY_ATTRIBUTES securityAttributes;
	//char secDesc[SECURITY_DESCRIPTOR_MIN_LENGTH];
	securityAttributes.nLength = sizeof(securityAttributes);
	securityAttributes.bInheritHandle = FALSE;
	//securityAttributes.lpSecurityDescriptor = &secDesc;

	if (!InitializeSecurityDescriptor(securityAttributes.lpSecurityDescriptor, SECURITY_DESCRIPTOR_REVISION)) 
	{  
		pantheios::log_ERROR("[GetSecurityAttributes] InitializeSecurityDescriptor failed error:", panint(GetLastError()));
		return false;	
	} 

	// Add the ACL to the security descriptor. 
	if (!SetSecurityDescriptorDacl(securityAttributes.lpSecurityDescriptor, TRUE, 0, FALSE))   // not a default DACL 
	{  
		pantheios::log_ERROR("[GetSecurityAttributes] SetSecurityDescriptorDacl failed error:", panint(GetLastError()));
		return false;			
	} 


	//PSECURITY_DESCRIPTOR pSD;
	//ConvertStringSecurityDescriptorToSecurityDescriptorA("S:(ML;;NW;;;LW)", // this means "low integrity"
	//	SDDL_REVISION_1,
	//	&pSD,
	//	NULL);
	//PACL pSacl = NULL;         // not allocated
	//BOOL fSaclPresent = FALSE;
	//BOOL fSaclDefaulted = FALSE;
	//GetSecurityDescriptorSacl(pSD,
	//	&fSaclPresent,
	//	&pSacl,
	//	&fSaclDefaulted);
	//SetSecurityDescriptorSacl(securityAttributes.lpSecurityDescriptor, TRUE, pSacl, FALSE);


	return true;
}




bool Broadcast::InitSharedMQ(unsigned int index, unsigned int sersize, char* suffix)
{
	SECURITY_ATTRIBUTES securityAttributes;
	char secDesc[SECURITY_DESCRIPTOR_MIN_LENGTH];
	securityAttributes.lpSecurityDescriptor = &secDesc;

	if (!GetSecurityAttributes(securityAttributes))   
	{  
		pantheios::log_ERROR("[InitSharedMQ] GetSecurityAttributes failed error:", panint(GetLastError()));
		return false;			
	} 


	unsigned int map_size = sersize * sizeof(BarData) + sizeof(unsigned int);
	
	
	char ch[100];
	GetCharName(suffix, ch);
		

	// Create the file mapping object.
	m_shmarr[index].hMapFile_barser = CreateFileMapping(
		INVALID_HANDLE_VALUE,   // Use paging file - shared memory
		&securityAttributes,                   // Default security attributes
		PAGE_READWRITE,         // Allow read and write access
		0,                      // High-order DWORD of file mapping max size
		map_size,				 // Low-order DWORD of file mapping max size
		ch           // Name of the file mapping object
		);
	if (m_shmarr[index].hMapFile_barser == NULL) 
	{
		pantheios::log_ERROR("[InitSharedMQ] CreateFileMapping failed error:", panint(GetLastError()));
		DestroySharedMQ(index);
		return false;
	}
	//printf("[InitSharedMQ] The file mapping (%s) is created\n", ch);
	pantheios::log_NOTICE("[InitSharedMQ] The file mapping (", ch, ") is created");

	


	// Map a view of the file mapping into the address space of the current process.
	m_shmarr[index].pView_barser = MapViewOfFile(
		m_shmarr[index].hMapFile_barser,               // Handle of the map object
		FILE_MAP_ALL_ACCESS,    // Read and write access
		0,                      // High-order DWORD of the file offset 
		0,			            // Low-order DWORD of the file offset 
		map_size   // The number of bytes to map to view
		);
	if (m_shmarr[index].pView_barser == NULL)
	{ 
		pantheios::log_ERROR("[InitSharedMQ] MapViewOfFile failed error:", panint(GetLastError()));
		DestroySharedMQ(index);
		return false;
	}
	pantheios::log_NOTICE("[InitSharedMQ] The file view (", ch, ") is mapped");


	memset(m_shmarr[index].pView_barser, 0, map_size);


	m_shmarr[index].pindex_barser = new (m_shmarr[index].pView_barser) unsigned int;


	unsigned int* p = (unsigned int*)m_shmarr[index].pView_barser;

	p++;

	m_shmarr[index].pmq_barser = (BarData*) p;

	//LocalFree(security.lpSecurityDescriptor);
	return true;
}



void Broadcast::DestroySharedMQ(unsigned int index)
{

	if (m_shmarr[index].hMapFile_barser)
	{
		if (m_shmarr[index].pView_barser)
		{
			// Unmap the file view.
			UnmapViewOfFile(m_shmarr[index].pView_barser);
			m_shmarr[index].pView_barser = NULL;
		}
		// Close the file mapping object.
		CloseHandle(m_shmarr[index].hMapFile_barser);
		m_shmarr[index].hMapFile_barser = NULL;
	}
}

bool Broadcast::InitSharedSemRecord(unsigned int index, char* suffix)
{
	SECURITY_ATTRIBUTES securityAttributes;
	char secDesc[SECURITY_DESCRIPTOR_MIN_LENGTH];
	securityAttributes.lpSecurityDescriptor = &secDesc;

	if (!GetSecurityAttributes(securityAttributes))   
	{  
		pantheios::log_ERROR("[InitSharedSemRecord] GetSecurityAttributes failed error:", panint(GetLastError()));
		return false;			
	} 

	unsigned int map_size = sizeof(semrecord) * SEMRECORD_MAPSIZE + sizeof(unsigned int);


	char ch[100];
	GetCharName(suffix, ch);


	// Create the file mapping object.
	m_shmarr[index].hMapFile_semrec = CreateFileMapping(
		INVALID_HANDLE_VALUE,   // Use paging file - shared memory
		&securityAttributes,                   // Default security attributes
		PAGE_READWRITE,         // Allow read and write access
		0,                      // High-order DWORD of file mapping max size
		map_size,				 // Low-order DWORD of file mapping max size
		ch           // Name of the file mapping object
		);
	if (m_shmarr[index].hMapFile_semrec == NULL) 
	{
		pantheios::log_ERROR("[InitSharedSemRecord] CreateFileMapping failed error:", panint(GetLastError()));
		DestroySharedSemRecord(index);
		return false;
	}
	//printf("[InitSharedSemRecord] The file mapping (%s) is created\n", ch); 

	pantheios::log_NOTICE("[InitSharedSemRecord] The file view (", ch, ") is created");



	// Map a view of the file mapping into the address space of the current process.
	m_shmarr[index].pView_semrec = MapViewOfFile(
		m_shmarr[index].hMapFile_semrec,               // Handle of the map object
		FILE_MAP_ALL_ACCESS,    // Read and write access
		0,                      // High-order DWORD of the file offset 
		0,			            // Low-order DWORD of the file offset 
		map_size   // The number of bytes to map to view
		);
	if (m_shmarr[index].pView_semrec == NULL)
	{ 
		pantheios::log_ERROR("[InitSharedSemRecord] MapViewOfFile failed error:", panint(GetLastError()));
		DestroySharedSemRecord(index);
		return false;
	}
	//printf("[InitSharedSemRecord] The file view (%s) is mapped\n", ch);

	pantheios::log_NOTICE("[InitSharedSemRecord] The file view (", ch, ") is mapped");


	m_shmarr[index].psize_semrec = new (m_shmarr[index].pView_semrec) unsigned int;

	unsigned int* p = (unsigned int*)m_shmarr[index].pView_semrec;
	p++;

	m_shmarr[index].pmq_semrec =  (semrecord*) p;

	//m_shmarr[index].pvsem_semrec = new (p) vector<semrecord>;

	return true;
}

void Broadcast::DestroySharedSemRecord(unsigned int index)
{
	CleanSharedsema(index);
	
	if (m_shmarr[index].hMapFile_semrec)
	{
		if (m_shmarr[index].pView_semrec)
		{
			// Unmap the file view.
			UnmapViewOfFile(m_shmarr[index].pView_semrec);
			m_shmarr[index].pView_semrec = NULL;
		}
		// Close the file mapping object.
		CloseHandle(m_shmarr[index].hMapFile_semrec);
		m_shmarr[index].hMapFile_semrec = NULL;
	}
}

bool Broadcast::InitMutex()
{
	SECURITY_ATTRIBUTES securityAttributes;
	char secDesc[SECURITY_DESCRIPTOR_MIN_LENGTH];
	securityAttributes.lpSecurityDescriptor = &secDesc;

	if (!GetSecurityAttributes(securityAttributes))   
	{  
		pantheios::log_ERROR("[InitMutex] GetSecurityAttributes failed error:", panint(GetLastError()));

		return false;			
	} 



	char ch[100];
	GetCharName("mutex", ch);


	m_mutex = CreateMutex( 
		&securityAttributes,                        // default security descriptor
		FALSE,                       // mutex not owned
		ch);  // object name


	if (m_mutex == NULL) 
	{
		//printf("[InitMutex]CreateMutex error: %d\n", GetLastError() ); 
		pantheios::log_ERROR("[InitMutex] CreateMutex failed error:", panint(GetLastError()));

		DestroyMutex();
		return false;
	}

	if (GetLastError() == ERROR_ALREADY_EXISTS)
		pantheios::log_WARNING("[InitMutex] ", ch, "already exists");
	else
		//printf("[InitMutex] Created a new mutex:%s.\n", ch);
		pantheios::log_NOTICE("[InitMutex] Created a new mutex:", ch);


	return true;	
}


void Broadcast::DestroyMutex()
{
	if (m_mutex)
	{
		CloseHandle(m_mutex);
		m_mutex = NULL;
	}
}



bool Broadcast::DeleteCursema(semrecord* pstart_semrec, unsigned int size_semrec, unsigned int curindex_semrec)
{

	for (unsigned int i = curindex_semrec + 1; i <= size_semrec; i++)
	{
		semrecord* psource = pstart_semrec + i;
		semrecord* pdest = psource - 1;
		memcpy(pdest, psource, sizeof(semrecord));
	}


	return true;
}


bool Broadcast::CloseSharedsema(semrecord* psemrecord)
{
	if (psemrecord->han)
	{
		if (false == CloseHandle(psemrecord->han))
		{
			pantheios::log_ERROR("[CloseSharedsema] CloseHandle:", psemrecord->semname, " Error:", panint(GetLastError()));

			psemrecord->han = NULL;

			return false;
		}

		psemrecord->han = NULL;

	}


	return true;
}





bool Broadcast::OpenSharedsema(semrecord* psemrecord)
{

	if (0 != strlen(psemrecord->semname))	//Not empty, so open the semaphore
	{
		psemrecord->han = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, psemrecord->semname);

		if (psemrecord->han == NULL) 
		{
			pantheios::log_ERROR("[OpenSharedsema] OpenSemaphore:", psemrecord->semname, " Error:", panint(GetLastError()));
			return false;
		}
	} 
	else
	{
		pantheios::log_ERROR("[OpenSharedsema] Empty semname");
		return false;
	}

	return true;
}


void Broadcast::BroadcastMessage(MarketData *pDepthMarketData)
{
	WaitForSingleObject (m_mutex, INFINITE);


	unsigned int size = sizeof(m_shmarr)/sizeof(SharedMemory);
	for (unsigned int i = 0; i < size; i++)
	{
		//copy data to mq and set index
		//printf("[BroadcastMessage] b4 Addtick\n");
		if (0 ==RUN_STATE || 1 ==RUN_STATE)
		{
			m_pbarserbroad[i]->Addtick(pDepthMarketData);
		} 
		else
		{
			if (false == m_pbarserbroad[i]->Addtick(pDepthMarketData))
			{
				ReleaseMutex(m_mutex);
				return;
			}
		}
		
		
		BarData* pstart_barser = m_shmarr[i].pmq_barser;
		unsigned int index_barser = *m_shmarr[i].pindex_barser;
				


		if (0 == i)
		{
			int stop = 0;
			pantheios::log_NOTICE("[BM] ", m_stringInst, ":", panint(i), " lp:", panreal(pstart_barser[index_barser].LastPrice), " index:", panint(index_barser));

		}



		//send semaphore/open and send/delete	
		semrecord* pstart_semrec = m_shmarr[i].pmq_semrec;
		int size_semrec = (int)(*m_shmarr[i].psize_semrec);
		for (int index_semrec = 0; index_semrec < size_semrec; index_semrec++)// should use int not unsigned int, may -1
		{
			semrecord* pcur_semrec = pstart_semrec + index_semrec;

			if (NULL != pcur_semrec->han && false != pcur_semrec->bactive)
			{
				pantheios::log_NOTICE("[BM] ", m_stringInst, ":", panint(i), " lp:", panreal(pstart_barser[index_barser].LastPrice), " index:", panint(index_barser), " rel:", pcur_semrec->semname);

				long precnt = 0;
				ReleaseSemaphore(pcur_semrec->han, 1, &precnt);
				if (0 != precnt)
					pantheios::log_WARNING("[BM] delay previous semaphore:", pcur_semrec->semname, " cnt is:", panint(precnt));

			} 
			else if (NULL == pcur_semrec->han && false != pcur_semrec->bactive)
			{
				if (true == OpenSharedsema(pcur_semrec))
				{
					pantheios::log_WARNING("[BM] ", m_stringInst, ":", panint(i), " lp:", panreal(pstart_barser[index_barser].LastPrice), " index:", panint(index_barser), " Openrel:", pcur_semrec->semname);


					long precnt = 0;
					ReleaseSemaphore(pcur_semrec->han, 1, &precnt);
					if (0 != precnt)
						pantheios::log_WARNING("[BM] delay previous semaphore:", pcur_semrec->semname, " cnt is:", panint(precnt));

				}
				else
				{
					// for the condition
					// client add name and set active but server hasn't open sharedsema
					// client app then is destroied abnormally(ie. press OK btn to force close),so when the server is ready to OpenSharedsema it would be false, 
					// delete it
					
					DeleteCursema(pstart_semrec, size_semrec, index_semrec);

					//set shm variable 
					(*m_shmarr[i].psize_semrec)--;

					//reset these two for next turn
					size_semrec = *m_shmarr[i].psize_semrec;
					//if (index_semrec > 0)
						index_semrec--;
				}
			}
			else if (NULL != pcur_semrec->han && false == pcur_semrec->bactive)
			{
				if (true == CloseSharedsema(pcur_semrec))
				{
					pantheios::log_WARNING("[BM] ", m_stringInst, ":", panint(i), " lp:", panreal(pstart_barser[index_barser].LastPrice), " index:", panint(index_barser), " Close:", pcur_semrec->semname);


					DeleteCursema(pstart_semrec, size_semrec, index_semrec);

					//set shm variable 
					(*m_shmarr[i].psize_semrec)--;

					//reset these two for next turn
					size_semrec = *m_shmarr[i].psize_semrec;
					//if (index_semrec > 0)
						index_semrec--;
				
				}
				else{}//for this condition, there is log in CloseSharedsema
					
			}
			else
			{
				pantheios::log_WARNING("[BM] Clean unactive sema:", pcur_semrec->semname);

				// for the condition
				// client set name and active successed firstly.
				// and then set unactive unsuccessed.
				// because the name still uncovered to zero. so delete it
				DeleteCursema(pstart_semrec, size_semrec, index_semrec);

				//set shm variable 
				(*m_shmarr[i].psize_semrec)--;

				//reset these two for next turn
				size_semrec = *m_shmarr[i].psize_semrec;
				//if (index_semrec > 0)
					index_semrec--;
			}
		}



	}



	ReleaseMutex(m_mutex);
}




void Broadcast::GetCharName(const char* pname, char* pchar)
{
	//string prefix = "Global\\";
	string prefix = SHARENAME_PREFIX;
	//prefix += m_barinfo.instru;
	prefix += m_stringInst;
	prefix += "_";
	string fullname = prefix + pname;
	strcpy(pchar, fullname.c_str());
	
}

void Broadcast::GetSharedMq(BarSeries_broad** &ppbarserbroad/*out*/, unsigned int* pcnt/*out*/)
{
	ppbarserbroad = m_pbarserbroad;
	*pcnt = sizeof(m_shmarr)/sizeof(SharedMemory);
}

bool Broadcast::CleanSharedsema(unsigned int index)
{
	WaitForSingleObject (m_mutex, INFINITE);


	semrecord* pstart_semrec = m_shmarr[index].pmq_semrec;
	int size_semrec = (int)(*m_shmarr[index].psize_semrec);
	for (int index_semrec = 0; index_semrec < size_semrec; index_semrec++)// should use int not unsigned int, may -1
	{
		semrecord* pcur_semrec = pstart_semrec + index_semrec;

		
		if (pcur_semrec->han && pcur_semrec->bactive)
		{
			pantheios::log_WARNING("[CleanSharedsema] ", pcur_semrec->semname, " VALID---ACTIVE");

			if (true == CloseSharedsema(pcur_semrec))
			{
				pantheios::log_WARNING("[CleanSharedsema] ", m_stringInst, ":", panint(index),  " Close:", pcur_semrec->semname);


				//only close sema not delet it in semarecord
			}
			else{}//for this condition, there is log in CloseSharedsema
		}
		else if (NULL == pcur_semrec->han && pcur_semrec->bactive)
		{
			pantheios::log_WARNING("[CleanSharedsema] ", pcur_semrec->semname, " INVALID---ACTIVE");
		}
		else if (pcur_semrec->han && false == pcur_semrec->bactive)
		{
			pantheios::log_WARNING("[CleanSharedsema] ", pcur_semrec->semname, " VALID---UNACTIVE");

			if (true == CloseSharedsema(pcur_semrec))
			{
				pantheios::log_WARNING("[CleanSharedsema] ", m_stringInst, ":", panint(index),  " Close:", pcur_semrec->semname);

				DeleteCursema(pstart_semrec, size_semrec, index_semrec);

				//set shm variable 
				(*m_shmarr[index].psize_semrec)--;

				//reset these two for next turn
				size_semrec = *m_shmarr[index].psize_semrec;
				//if (index_semrec > 0)
				index_semrec--;
			}
			else{}//for this condition, there is log in CloseSharedsema

		}
		else if (NULL == pcur_semrec->han && false == pcur_semrec->bactive)
		{
			pantheios::log_WARNING("[CleanSharedsema] ", pcur_semrec->semname, " INVALID---UNACTIVE");

			//pantheios::log_WARNING("[CleanSharedsema] Clean unactive sema:", pcur_semrec->semname);

			// for the condition
			// client set name and active successed firstly.
			// and then set unactive unsuccessed.
			// because the name still uncovered to zero. so delete it
			DeleteCursema(pstart_semrec, size_semrec, index_semrec);

			//set shm variable 
			(*m_shmarr[index].psize_semrec)--;

			//reset these two for next turn
			size_semrec = *m_shmarr[index].psize_semrec;
			//if (index_semrec > 0)
			index_semrec--;
		}

		//if (NULL != pcur_semrec->han)
		//{
		//	pantheios::log_WARNING("[CleanSharedsema] ", pcur_semrec->semname, " NOT NULL");

		//	if (true == CloseSharedsema(pcur_semrec))
		//	{
		//		pantheios::log_WARNING("[CleanSharedsema] ", m_stringInst, ":", panint(index),  " Close:", pcur_semrec->semname);


		//		DeleteCursema(pstart_semrec, size_semrec, index_semrec);

		//		//set shm variable 
		//		(*m_shmarr[index].psize_semrec)--;

		//		//reset these two for next turn
		//		size_semrec = *m_shmarr[index].psize_semrec;
		//		//if (index_semrec > 0)
		//		index_semrec--;

		//	}
		//	else{}//for this condition, there is log in CloseSharedsema

		//}
		//else if (NULL == pcur_semrec->han && false == pcur_semrec->bactive)
		//{
		//	pantheios::log_WARNING("[CleanSharedsema] Clean unactive sema:", pcur_semrec->semname);

		//	// for the condition
		//	// client set name and active successed firstly.
		//	// and then set unactive unsuccessed.
		//	// because the name still uncovered to zero. so delete it
		//	DeleteCursema(pstart_semrec, size_semrec, index_semrec);

		//	//set shm variable 
		//	(*m_shmarr[index].psize_semrec)--;

		//	//reset these two for next turn
		//	size_semrec = *m_shmarr[index].psize_semrec;
		//	//if (index_semrec > 0)
		//	index_semrec--;
		//}
	}

	ReleaseMutex(m_mutex);

	return true;
}

bool Broadcast::RenewSharedMq()
{
	unsigned int size = sizeof(m_shmarr)/sizeof(SharedMemory);
	for (unsigned int i = 0; i < size; i++)
	{
		if (m_pbarserbroad[i])
		{
			delete m_pbarserbroad[i];
			m_pbarserbroad[i] = NULL;
		}
			



		unsigned sersize  = 0;
		BarInfo barinfo;
		strcpy(barinfo.instru, m_stringInst.c_str());
		barinfo.cnt = 1;
		if (0 == i)
		{
			sersize = DEFAULT_TICKSERSIZE_OFDAY;
			barinfo.type = Bartype::tick;
		}		
		else if (1 == i)
		{
			sersize = DEFAULT_SECSERSIZE_OFDAY;;
			barinfo.type = Bartype::sec;
		}
		else if (2 == i)
		{
			sersize = DEFAULT_MINSERSIZE_OFDAY;
			barinfo.type = Bartype::min;
		}
		else if (3 == i)
		{
			sersize = DEFAULT_DAYSERSIZE_OFDAY;
			barinfo.type = Bartype::day;
		}

		

		m_pbarserbroad[i] = new BarSeries_broad(&barinfo, sersize, NULL, m_shmarr[i].pmq_barser, m_shmarr[i].pindex_barser);
		if (NULL == m_pbarserbroad[i])
		{
			printf("[RenewSharedMq] m_pbarserbroad:%d init failed\n", i);
			return false;
		}

	}

	return true;
}


//
//BOOL Broadcast::AnsiToUnicode16(CHAR *in_Src, WCHAR *out_Dst, INT in_MaxLen)
//{   
//	/* locals */   
//	INT lv_Len; 
//	// do NOT decrease maxlen for the eos  if (in_MaxLen <= 0)    return FALSE; 
//	// let windows find out the meaning of ansi 
//	// - the SrcLen=-1 triggers MBTWC to add a eos to Dst and fails if MaxLen is too small.  
//	// - if SrcLen is specified then no eos is added 
//	// - if (SrcLen+1) is specified then the eos IS added  
//	lv_Len = MultiByteToWideChar(CP_ACP, 0, in_Src, -1, out_Dst, in_MaxLen);  
//	// validate  if (lv_Len < 0)    lv_Len = 0;  // ensure eos, watch out for a full buffersize 
//	// - if the buffer is full without an eos then clear the output like MBTWC does  
//	//   in case of too small outputbuffer  // - unfortunately there is no way to let MBTWC return shortened strings, 
//	//   if the outputbuffer is too small then it fails completely  
//	if (lv_Len < in_MaxLen)   
//		out_Dst[lv_Len] = 0;  
//	else if (out_Dst[in_MaxLen-1])   
//		out_Dst[0] = 0;  
//	// done 
//	return TRUE;
//}









































//bool Broadcast::InitSem()
//{
//	string prefix = m_pbar->instru;
//	prefix += "\\";
//	string sem_name = prefix + "sem";
//	char ch[100];
//	strcpy(ch, sem_name.c_str());
//	WCHAR wText[100];
//	if (false == AnsiToUnicode16(ch, 100))
//	{
//		printf("[InitSem] AnsiToUnicode16 failed\n");
//		return false;
//	}
//
//
//	m_sem[0] = CreateSemaphore(NULL, 0, 0);
//
//
//
//	if (m_sem[0] == NULL || GetLastError() == ERROR_ALREADY_EXISTS) 
//	{
//		printf("[InitSem]CreateSemaphore error: %d\n", GetLastError() ); 
//		return false;
//	}
//	printf("[InitSem] CreateSemaphore created a new sema[0]:%s.\n", sem_name);
//
//
//
//
//	m_sem[1] = CreateSemaphore(NULL, 0, 100, NULL); 
//	if (m_sem[1] == NULL || GetLastError() == ERROR_ALREADY_EXISTS) 
//	{
//		printf("[InitSem]CreateSemaphore error: %d\n", GetLastError() ); 
//		return false;
//	}
//	printf("[InitSem] CreateSemaphore created a new sema[1]\n");
//
//	return true;
//}
//
//
//bool Broadcast::InitSharedSemname()
//{
//	unsigned int map_size = 1024;
//
//
//	string prefix = m_pbar->instru;
//	prefix += "\\";
//	string map_name = prefix + "mapname_semnamequeue";
//	char ch[100];
//	strcpy(ch, map_name.c_str());
//	WCHAR wText[100];
//	if (false == AnsiToUnicode16(ch, 100))
//	{
//		printf("[InitSharedSemname] AnsiToUnicode16 failed\n");
//		return false;
//	}
//
//
//	// Create the file mapping object.
//	m_hMapFile_semname = CreateFileMapping(
//		INVALID_HANDLE_VALUE,   // Use paging file - shared memory
//		NULL,                   // Default security attributes
//		PAGE_READWRITE,         // Allow read and write access
//		0,                      // High-order DWORD of file mapping max size
//		map_size,				 // Low-order DWORD of file mapping max size
//		wText           // Name of the file mapping object
//		);
//	if (m_hMapFile_semname == NULL) 
//	{
//		printf("[InitSharedSemname] CreateFileMapping failed error:%d\n", GetLastError());
//		DestroySharedSemname();
//		return false;
//	}
//	printf("[InitSharedSemname]The file mapping (%s) is created\n", map_name); 
//
//
//
//	// Map a view of the file mapping into the address space of the current process.
//	m_pView_semname = MapViewOfFile(
//		m_hMapFile_semname,               // Handle of the map object
//		FILE_MAP_ALL_ACCESS,    // Read and write access
//		0,                      // High-order DWORD of the file offset 
//		0,			            // Low-order DWORD of the file offset 
//		map_size   // The number of bytes to map to view
//		);
//	if (m_pView_semname == NULL)
//	{ 
//		printf("[InitSharedSemname] MapViewOfFile failed err %d\n", GetLastError()); 
//		DestroySharedSemname();
//		return false;
//	}
//	printf("[InitSharedSemname] The file view is mapped\n");
//
//
//
//	m_psemname = (vector<string>*) m_pView_semname;
//
//
//	new (m_psemname) vector<string>;
//
//	return true;
//
//}
//
//
//void Broadcast::DestroySharedSemname()
//{
//
//	if (m_hMapFile_semname)
//	{
//		if (m_pView_semname)
//		{
//			// Unmap the file view.
//			UnmapViewOfFile(m_pView_semname);
//			m_pView_semname = NULL;
//		}
//		// Close the file mapping object.
//		CloseHandle(m_hMapFile_semname);
//		m_hMapFile_semname = NULL;
//	}
//
//}